"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 归档日志目录
Case Name   : 归档日志目录删除
Create At   : 2020/8/12
@zou_jialiang0505326387
Description :
    1、设置归档相关参数
    2、test1：删除归档目录，之后提交事务进行归档操作
    3、test2：执行提交事务脚本正在归档，删除归档目录
Expect      :
    1、设置归档相关参数成功
    2、重启数据库成功
    3、test1：删除归档目录，之后提交事务进行归档操作，pg日志打印相应报错，数据库状态正常
    4、test2：执行提交事务脚本正在归档，删除归档目录，数据库状态正常
History     :
    2021/05/17 modified by @peilinqian 优化脚本逻辑，增加必要打印信息;增加test2故障结果逻辑处理
"""

import os
import time
import unittest

from testcase.utils.ComThread import ComThread
from testcase.utils.Common import Common
from testcase.utils.CommonSH import *
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class NoneArchivePath(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.log = Logger()
        cls.log.info('----Opengauss_Reliability_Dbsys_Case035.py start----')
        cls.dbUserNode = Node(node='dbuser')
        cls.conf_path = os.path.join(macro.DB_INSTANCE_PATH,
                                     macro.DB_PG_CONFIG_NAME)
        cls.log.info(cls.conf_path)
        cls.arch_path = macro.ARCH_PATH
        cls.node_name = macro.DN_NODE_NAME.split('/')[0]
        cls.log_path = os.path.join(macro.PG_LOG_PATH, cls.node_name)
        cls.log.info(cls.log_path)
        cls.sh = CommonSH()
        cls.com = Common()
        cls.Constant = Constant()

    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log.info('----1、修改归档参数----')
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   'archive_mode = on')
        self.assertTrue(msg)
        arch_command = f'cp --remove-destination %p {self.arch_path}/%f'
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   f"archive_command ='{arch_command}'")
        self.assertTrue(msg)
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   'archive_timeout = 30')
        self.assertTrue(msg)
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   'checkpoint_segments = 10')
        self.assertTrue(msg)

        self.log.info('----修改配置文件成功----')
        sql_result = self.sh.executDbSql('show archive_mode;'
                                         'show archive_command;'
                                         'show archive_timeout;'
                                         'show checkpoint_segments;')
        self.log.info(sql_result)

    def test_del_archivepath1(self):
        self.log.info('----test1：删除归档目录，之后提交事务进行归档操作----')
        self.log.info('----查询归档路径----')
        exits_cmd = f'ls {self.arch_path}'
        self.log.info(exits_cmd)
        exits_msg = self.dbUserNode.sh(exits_cmd).result()
        self.log.info(exits_msg)
        if self.Constant.NO_FILE_MSG not in exits_msg:
            self.log.info('----删除归档路径----')
            rm_cmd = f'rm -vrf {self.arch_path}'
            self.log.info(rm_cmd)
            self.dbUserNode.sh(rm_cmd).result()
            exits_cmd = f'ls {self.arch_path}'
            exits_msg = self.dbUserNode.sh(exits_cmd).result()
            self.log.info(exits_msg)
            self.assertIn(self.Constant.NO_FILE_MSG, exits_msg)

        self.log.info('----开始执行插入事务----')
        msg = self.com.createLargeNumTable(self.dbUserNode,
                                           't_test',
                                           1,
                                           1000000)
        self.log.info(msg)

        self.log.info('----查询主备状态----')
        status = self.sh.getDbClusterStatus('status')
        self.assertTrue(status)

        self.log.info('----查看日志关键信息----')
        time.sleep(120)
        find_file_cmd = f'ls -t {self.log_path} |head -n1'
        self.log.info(find_file_cmd)
        msg = self.dbUserNode.sh(find_file_cmd).result()
        self.log.info(msg)
        cat_file_cmd = f'cat {os.path.join(self.log_path, msg)}'
        self.log.info(cat_file_cmd)
        msg = self.dbUserNode.sh(cat_file_cmd).result()
        self.log.info(msg)
        self.assertIn(self.Constant.FAILED_ARCHIVE_MSG, msg)

    def test_del_archivepath2(self):
        self.log.info('----test2：执行提交事务脚本正在归档，删除归档目录----')
        self.log.info('----查询归档路径----')
        exits_cmd = f'ls {self.arch_path}'
        self.log.info(exits_cmd)
        exits_msg = self.dbUserNode.sh(exits_cmd).result()
        self.log.info(exits_msg)
        if self.Constant.NO_FILE_MSG in exits_msg:
            self.log.info('----不存在目录进行目录创建----')
            mk_cmd = f'mkdir {self.arch_path}'
            msg = self.dbUserNode.sh(mk_cmd).result()
            self.assertEqual(msg, '')
            self.log.info('----查询归档路径----')
            exits_cmd = f'ls {self.arch_path}'
            self.log.info(exits_cmd)
            exits_msg = self.dbUserNode.sh(exits_cmd).result()
            self.log.info(exits_msg)

        self.log.info('----启动新线程插入数据----')
        insert_thread = ComThread(self.com.createLargeNumTable,
                                  args=(self.dbUserNode,
                                        't_test',
                                        1,
                                        10000000,))
        insert_thread.setDaemon(True)
        insert_thread.start()

        time.sleep(5)

        self.log.info('----提交事务正在归档的时候删除归档目录----')
        self.log.info('----查询归档路径----')
        exits_cmd = f'ls {self.arch_path}'
        self.log.info(exits_cmd)
        exits_msg = self.dbUserNode.sh(exits_cmd).result()
        self.log.info(exits_msg)
        self.log.info('----删除归档路径----')
        rm_cmd = f'rm -vrf {self.arch_path}'
        self.log.info(rm_cmd)
        rm_result = self.dbUserNode.sh(rm_cmd).result()
        self.log.info(rm_result)
        exits_cmd = f'ls {self.arch_path}'
        exits_msg = self.dbUserNode.sh(exits_cmd).result()
        self.log.info(exits_msg)
        if 'cannot remove' in rm_result:
            self.log.info('归档过程删除归档路径失败！！！')
        else:
            self.assertIn(self.Constant.NO_FILE_MSG, exits_msg)

        self.log.info('----插入数据正常完成----')
        insert_thread.join()
        insert_result = insert_thread.get_result()
        self.log.info(insert_result)
        self.assertIn('INSERT 0 10000000', insert_result)

        self.log.info('----查询主备状态----')
        status = self.sh.getDbClusterStatus('status')
        self.assertTrue(status)

    def tearDown(self):
        self.log.info('----恢复归档参数----')
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   'archive_mode = off')
        self.assertTrue(msg)
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   'archive_timeout = 0')
        self.assertTrue(msg)
        msg = self.sh.executeGsguc('reload', self.Constant.GSGUC_SUCCESS_MSG,
                                   'checkpoint_segments = 64')
        self.assertTrue(msg)

        self.log.info('----修改配置文件成功----')
        sql_result = self.sh.executDbSql('show archive_mode;'
                                         'show archive_command;'
                                         'show archive_timeout;'
                                         'show checkpoint_segments;')
        self.log.info(sql_result)

        self.log.info('----清理数据----')
        msg = self.com.createLargeNumTable(self.dbUserNode,
                                           't_test',
                                           del_sign=True)
        self.log.info(msg)

        self.log.info('----删除创建的文件----')
        exits_cmd = f'ls {self.arch_path}'
        msg = self.dbUserNode.sh(exits_cmd).result()
        if self.Constant.NO_FILE_MSG not in msg:
            rm_cmd = f'rm -vrf {self.arch_path}'
            self.log.info(rm_cmd)
            self.dbUserNode.sh(rm_cmd).result()
            exits_cmd = f'ls {self.arch_path}'
            exits_result = self.dbUserNode.sh(exits_cmd).result()
            self.log.info(exits_result)

        self.log.info('----reliability_dbsys035 执行完成----')
